/*
 * Copyright (C) 2015 Daniel Uppenkamp
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.maurersmarbles.desktop;

import com.google.common.base.Preconditions;
import com.googlecode.maurersmarbles.ScreenCanvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;

/**
 *
 * @author Daniel Uppenkamp
 */
public class DesktopScreenCanvas extends ScreenCanvas {

    /**
     * The graphics that is used to draw the drawables.
     */
    protected Graphics graphics;

    /**
     * Creates a new DesktopScreenCanvas.
     */
    public DesktopScreenCanvas() {
        // do nothing
    }

    /**
     * Returns the max font size that fits within the given width and height.
     * @param graphics the graphics
     * @param font the font
     * @param string the string
     * @param width the width of the bounding box
     * @param height the height of the bounding box 
     * @return the max font size that fits within the given width and height
     */
    public static int getMaxFittingFontSize(Graphics graphics, Font font, String string, int width, int height) {
        
        int minSize = 0;
        int maxSize = 288;
        int currentSize = font.getSize();
        
        while(maxSize - minSize > 2) {
            FontMetrics fontMetrics = graphics.getFontMetrics(new Font(font.getName(), font.getStyle(), currentSize));
            int fontWidth = fontMetrics.stringWidth(string);
            int fontHeight = fontMetrics.getLeading() + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent();
            
            if((fontWidth > width) || (fontHeight > height)) {
                maxSize = currentSize;
                currentSize = (maxSize + minSize) / 2;
            }
            else {
                minSize = currentSize;
                currentSize = (minSize + maxSize) / 2;
            }
        }
        
        return currentSize;
        
    }
    
    /**
     * Sets the graphics that is used to draw the drawables.
     *
     * @param graphics the graphics that is used to draw the drawables
     */
    public void setGraphics(Graphics graphics) {
        this.graphics = graphics;
    }

    @Override
    public void drawLine(int x1, int y1, int x2, int y2, int rgb) {
        if (graphics != null) {
            graphics.setColor(new Color(rgb));
            graphics.drawLine(x1, y1, x2, y2);
        }
    }

    @Override
    public void drawOval(int x, int y, int width, int height, int rgb) {
        if (graphics != null) {
            graphics.setColor(new Color(rgb));
            graphics.drawOval(x, y, width, height);
        }
    }

    @Override
    public void drawRect(int x, int y, int width, int height, int rgb) {
        if (graphics != null) {
            graphics.setColor(new Color(rgb));
            graphics.drawRect(x, y, width, height);
        }
    }

    @Override
    public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int argHeight, int rgb) {
        if (graphics != null) {
            graphics.setColor(new Color(rgb));
            graphics.drawRoundRect(x, y, width, height, arcWidth, argHeight);
        }
    }
    
    @Override
    public void drawStringCentered(String string, int x, int y, int width, int height, int rgb) {

        Preconditions.checkNotNull(string, "Null string");

        if (graphics != null) {

            graphics.setColor(new Color(rgb));

            // TODO Either update the interface to include a size or figure out how to determine this
//            int size = getMaxFittingFontSize(graphics, new Font(Font.SANS_SERIF, Font.BOLD, 10), string, (int)(width * 0.75), (int)(height * 0.75));
//            graphics.setFont(new Font(Font.SANS_SERIF, Font.BOLD, size));
            
            FontMetrics fontMetrics = graphics.getFontMetrics();
            int startX = x + (width - fontMetrics.stringWidth(string)) / 2;
            int startY = y + (fontMetrics.getAscent() + (height - (fontMetrics.getAscent() + fontMetrics.getDescent())) / 2);
            graphics.drawString(string, startX, startY);

        }

    }

    @Override
    public void fillOval(int x, int y, int width, int height, int rgb) {
        if (graphics != null) {
            graphics.setColor(new Color(rgb));
            graphics.fillOval(x, y, width, height);
        }
    }

    @Override
    public void fillRect(int x, int y, int width, int height, int rgb) {
        if (graphics != null) {
            graphics.setColor(new Color(rgb));
            graphics.fillRect(x, y, width, height);
        }
    }

    @Override
    public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int argHeight, int rgb) {
        if (graphics != null) {
            graphics.setColor(new Color(rgb));
            graphics.fillRoundRect(x, y, width, height, arcWidth, argHeight);
        }
    }

}
